﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.AccessControl;
using System.Text;

namespace Downloader
{
    public static class HtmlByUrl
    {
        private const int Buff = 1024;

        public static string GetStringHtmlByUrl(string url)
        {
            return GetStringHtmlByUrl(url, null);
        }

        public static string GetStringHtmlByUrl(string url, string content)
        {
            try
            {
                var req = WebRequest.Create(url);
                if (!string.IsNullOrEmpty(content))
                {
                    var bytes = Encoding.Default.GetBytes(content);
                    req.Method = "POST";
                    req.ContentLength = bytes.Length;
                    req.ContentType = "text/xml";
                    using (var requestStream = req.GetRequestStream())
                    {
                        requestStream.Write(bytes, 0, bytes.Length);
                    }
                }
                using (var res = req.GetResponse())
                {
                    using (var streamReader = new StreamReader(res.GetResponseStream(), Encoding.Default))
                    {
                        return streamReader.ReadToEnd();
                    }
                }
            }
            catch (Exception)
            {
                return "";
            }
        }

        public static string GetResponseUrl(string url)
        {
            try
            {
                var req = WebRequest.Create(url);
                using (var res = req.GetResponse())
                {
                    return res.ResponseUri.AbsoluteUri;
                }
            }
            catch (Exception)
            {
                return "";
            }
        }

        public static byte[] DownloadData(string url)
        {
            try
            {

                if (string.IsNullOrEmpty(url))
                    return new byte[0];
                var req = WebRequest.Create(url);
                using (var response = req.GetResponse())
                {
                    using (var stream = response.GetResponseStream())
                    {

                        var buffer = new byte[Buff];

                        using (var memStream = new MemoryStream())
                        {
                            while (true)
                            {
                                var bytesRead = stream.Read(buffer, 0, buffer.Length);

                                if (bytesRead == 0)
                                    break;
                                memStream.Write(buffer, 0, bytesRead);
                            }

                            return memStream.ToArray();
                        }
                    }
                }
            }
            catch
            {
                if (!File.Exists(url))
                    return null;
                try
                {
                    using (var stream = new FileStream(url, FileMode.Open, FileAccess.Read))
                    {
                        var buffer = new byte[Buff];

                        using (var memStream = new MemoryStream())
                        {
                            while (true)
                            {
                                var bytesRead = stream.Read(buffer, 0, buffer.Length);

                                if (bytesRead == 0)
                                    break;
                                memStream.Write(buffer, 0, bytesRead);
                            }

                            return memStream.ToArray();
                        }
                    }
                }
                catch
                {
                    return null;
                }
            }
        }

        public static byte[] GetImage(string name)
        {
            var q =
                GetStringHtmlByUrl(string.Format(
                    //"http://images.google.com/images?tbs=isch:1&sa=1&q={0}&aq=f&aqi=&aql=&oq=",name));
                    "http://images.google.com/images?q={0}", name));
            if (q == null || q.Length < 1024)
                return null;
            var tb = q.IndexOf("<img")+1;
            if (tb <= 0)
                return null;
            tb = q.IndexOf("<img ", tb);
            if (tb <= 0)
                return null;
            tb = q.IndexOf("src=", tb);
            if (tb <= 0)
                return null;
            var url = "";
            tb += 4;
            for (var i =tb+1; i < q.Length; i++)
            {
                if (q[i] == q[tb])
                    break;
                url += q[i];
            }
            return string.IsNullOrEmpty(url) ? null : DownloadData(url);
        }

        public static byte[][] GetImages(string name, int count)
        {
            var res = new List<string>();
            var q =
                GetStringHtmlByUrl(string.Format(
                    "http://images.google.com/images?q={0}", name));
            if (q == null || q.Length < 1024)
                return null;
            var tb = q.IndexOf("<img") + 1;
            if (tb <= 0)
                return null;
            while (res.Count < count)
            {
                tb = q.IndexOf("<img ", tb);
                if (tb <= 0)
                    break;
                tb = q.IndexOf("src=", tb);
                if (tb <= 0)
                    break;
                var url = "";
                tb += 4;
                for (var i = tb + 1; i < q.Length; i++)
                {
                    if (q[i] == q[tb])
                        break;
                    url += q[i];
                }
                res.Add(url);
            }
            return res.Where(re => !string.IsNullOrEmpty(re)).Select(re => DownloadData(re)).Where(tm => tm != null && tm.Length > 0).ToArray();
        }

        public static string GetRealLink(string link, string path)
        {

            if (link.StartsWith("/"))
                return GetMainUrl(path) + link;
            if (!link.ToLower().StartsWith("www.") &&
                !link.ToLower().StartsWith("http://") &&
                !link.ToLower().StartsWith("https://") &&
                !link.ToLower().StartsWith("ftp://"))
                return GetMainUrl(path) + "/" + link;
            return link;
        }

        public static string GetMainUrl(string url)
        {
            if (string.IsNullOrEmpty(url))
                return url;
            var st = url.IndexOf("//") + 2;
            var lst = new List<int>
                          {
                              url.IndexOf("/", st),
                              url.IndexOf("?", st)
                          };
            var rs = lst.Where(item => item >= 0);
            return rs.Count() > 0 ? url.Remove(rs.Min()) : url;
        }

        public static Image ConvertByteArrayToImage(byte[] byteArray)
        {
            if (byteArray != null)
            {
                var ms = new MemoryStream(byteArray, 0,
                byteArray.Length);
                ms.Write(byteArray, 0, byteArray.Length);
                return Image.FromStream(ms, true);
            }
            return null;
        }
    }
}
